package com.jin.webvideo.base.linkedfile;

import com.jin.webvideo.base.StringKeyValuePairs;
import com.jin.webvideo.base.linkedfile.io.SeekableDataInputStream;

import java.io.IOException;
import java.io.Serial;
import java.io.Serializable;
import java.util.Locale;


public class LinkedItem implements Serializable {
    @Serial
    private static final long serialVersionUID = -2765921973938134266L;
    // 开始位置指针, 指示在虚拟文件中所处的位置
    private long start;
    // 长度指针，该文件的长度
    private long length;
    // 属性指针，指示该文件的实际属性的位置
    private long point = 0;
    // 偏移量指针，可用于文件头部伪装
    private long offset = 0;
    // 结束位置指针，文件中不存储，由start+length获得
    private long end;

    private boolean loaded = false;
    // 属性集
    private LinkedProperties properties;
    // 所属的linkedFile
    private LinkedFile linkedFile;

    public LinkedItem(LinkedFile linkedFile, long start, long offset, long length, long properties) {
        this(linkedFile, start, offset, length);
        this.point = properties;
    }

    public LinkedItem(LinkedFile linkedFile, long start, long offset, long length, LinkedProperties properties) {
        this.linkedFile = linkedFile;
        this.start = start;
        this.length = length;
        this.offset = offset;
        this.end = this.start + this.length;
        this.properties = properties;
    }
    public LinkedItem(LinkedFile linkedFile, long start, long offset, long length) {
        this(linkedFile, start, offset, length, null);
    }

    public void setStart(long start) {
        this.start = start;
    }

    public void setLength(long length) {
        this.length = length;
    }

    public void setOffset(long offset) {
        this.offset = offset;
    }

    public void setEnd(long end) {
        this.end = end;
    }

    public boolean isLoaded() {
        return loaded;
    }

    public void setLoaded(boolean loaded) {
        this.loaded = loaded;
    }

    public LinkedFile getLinkedFile() {
        return linkedFile;
    }

    public void setLinkedFile(LinkedFile linkedFile) {
        this.linkedFile = linkedFile;
    }

    public long getStart() {
        return start;
    }

    public long getLength() {
        return length;
    }

    public long getPoint() {
        return point;
    }

    public long getEnd() {
        return end;
    }

    public LinkedProperties getProperties() {
        return properties;
    }

    public void setPoint(long point) {
        this.point = point;
    }

    public void setProperties(LinkedProperties properties) {
        this.properties = properties;
    }

    // 加载属性集
    public void load() throws IOException {
        if (loaded) {
            return;
        }
        SeekableDataInputStream file = this.linkedFile.getInputStream();
        file.seek(this.point);
        int length = file.readUnsignedShort();
        int b = -1;
        StringBuilder builder = new StringBuilder();
        this.properties = new LinkedProperties();
        while(length-- > 0 && (b = file.read()) != -1) {
            if (b != 4) {
                builder.append((char) b);
                continue;
            }
            StringKeyValuePairs kvp = StringKeyValuePairs.createKeyValuePairs(builder.toString(), "\02");
            this.properties.put(kvp.getKey().toLowerCase(Locale.ROOT), kvp.getValue());
        }
        loaded = true;
    }

    public long getOffset() {
        return offset;
    }

    @Override
    public String toString() {
        return "DirItem{" +
                "start=" + start +
                ", offset=" + offset +
                ", length=" + length +
                ", point=" + point +
                ", end=" + end +
                ", properties=" + properties +
                '}';
    }
}
